package com.hczx.caxa.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

@Component
public class FTPUtil {

    private static Logger logger = LoggerFactory.getLogger(FTPUtil.class);

    @Value("${caxa.ftp.host}")
    private String host;
    @Value("${caxa.ftp.port}")
    private int port;
    @Value("${caxa.ftp.username}")
    private String username;
    @Value("${caxa.ftp.password}")
    private String password;

    private FTPClient getInstance() {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("UTF-8");

        try {
            ftpClient.connect(host, port);
            ftpClient.login(username, password);
            ftpClient.setControlEncoding("UTF-8");
            int replyCode = ftpClient.getReplyCode();

            if (!FTPReply.isPositiveCompletion(replyCode)) {
                logger.error("FTP服务（{}:{}）连接失败。", host, port);
                throw new Exception("FTP服务连接失败");
            }
            logger.info("FTP服务（{}:{}）连接成功。", host, port);

            ftpClient.enterLocalPassiveMode();

            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ftpClient;
    }

    private void changeWorkingDirectory(FTPClient ftpClient, String workingDirectory) throws IOException {
        String[] directories = workingDirectory.split("/");
        for (String directory : directories) {
            if (StringUtils.isBlank(directory)) {
                continue;
            }
            if (ftpClient.changeWorkingDirectory(directory)) {
                continue;
            }
            ftpClient.makeDirectory(directory);
            ftpClient.changeWorkingDirectory(directory);
        }
    }

    private void close(FTPClient client) {
        if (null == client) {
            return;
        }
        try {
            client.logout();
        } catch (Exception e) {
            logger.error("FTP退出登录失败。异常信息：{}", e.getMessage());
        } finally {
            if (client.isConnected()) {
                try {
                    client.disconnect();
                    logger.info("FTP断开连接成功。");
                } catch (Exception e) {
                    logger.error("FTP断开连接失败。异常信息：{}", e.getMessage());
                }
            }
        }
    }

    public void uploadFile(MultipartFile file, String fileName) {
        try (InputStream inputStream = file.getInputStream()) {
            FTPClient client = getInstance();
            if (client.storeFile(fileName, inputStream)) {
                logger.info("上传文件{}成功。", fileName);
            } else {
                logger.error("上传文件{}失败（{}）。", fileName, client.getReplyString());
            }
            close(client);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void upload(InputStream inputStream, String fileName) {
        try {
            FTPClient client = getInstance();
            if (client.storeFile(fileName, inputStream)) {
                logger.info("上传文件{}成功。", fileName);
            } else {
                logger.error("上传文件{}失败（{}）。", fileName, client.getReplyString());
            }
            close(client);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}